/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.aaron.platform.service;

import com.aaron.platform.dao.IUserDao;
import com.aaron.platform.dao.PageInfo;
import com.aaron.platform.entity.ItscRoleInfo;
import com.aaron.platform.exceptions.UserAlreadyExistException;
import com.aaron.platform.exceptions.UserNotExistException;
import com.aaron.platform.entity.ItscUserInfo;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.MatchMode;
import org.springframework.dao.DataAccessException;

/**
 *
 * @author chenzhuohua
 */
public class UserServiceImp implements IUserService {

    /**
     * 用户会话信息<会话ID,会话信息>
     */
    private final Map<String, UserSession> userSessions = new HashMap<String, UserSession>();
    /**
     * 用户DAO接口
     */
    private IUserDao userDao;

    public void setUserDao(IUserDao userDao) {
        this.userDao = userDao;
    }

    /**
     * 获取用户会话信息
     *
     * @param sessionId 会话ID
     * @return 会话信息
     */
    public UserSession getUserSession(String sessionId) {
        return userSessions.get(sessionId);
    }

    /**
     * 设置用户会话信息
     *
     * @param userSession 会话信息
     */
    public synchronized void addUserSession(UserSession userSession) {
        userSessions.put(userSession.getSessionId(), userSession);
    }

    /**
     * 删除用户会话信息
     *
     * @param userName 用户名
     */
    public synchronized void removeUserSession(String sessionId) {
        userSessions.remove(sessionId);
    }

    public ItscUserInfo findUserById(Integer userId) throws UserNotExistException {
        ItscUserInfo userInfo = userDao.findById(userId);
        if (userInfo == null) {
            throw new UserNotExistException();
        }
        return userInfo;
    }

    public ItscUserInfo findUserByName(String userName) throws UserNotExistException {
        //ItscUserInfo userInfo = userDao.findUserByName(userName);
        ItscUserInfo userInfo = userDao.findUserByName(userName);
        if (userInfo == null) {
            throw new UserNotExistException();
        }
        return userInfo;
    }

    public ItscUserInfo findUserByChName(String userChName) throws UserNotExistException {
        Properties properties = new Properties();
        properties.setProperty(ItscUserInfo.PROPERTY_USER_CHINESE_NAME, String.valueOf(userChName));
        List<ItscUserInfo> userInfos = findUsersByCondition(properties);
        if (userInfos != null) {
            return userInfos.get(0);
        } else {
            return null;
        }
    }

    public List<ItscUserInfo> findUsersByCondition(Properties condition) {

        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(ItscUserInfo.class);

        if (condition != null) {

            // user name
            String userName = condition.getProperty(ItscUserInfo.PROPERTY_USER_NAME);
            if (!StringUtils.isEmpty(userName)) {
                detachedCriteria = detachedCriteria.add(Expression.ilike(ItscUserInfo.PROPERTY_USER_NAME,
                        userName, MatchMode.ANYWHERE));
            }

            // user chinese name
            String userChName = condition.getProperty(ItscUserInfo.PROPERTY_USER_CHINESE_NAME);
            if (!StringUtils.isEmpty(userChName)) {
                detachedCriteria = detachedCriteria.add(Expression.ilike(ItscUserInfo.PROPERTY_USER_CHINESE_NAME,
                        userChName, MatchMode.ANYWHERE));
            }

            // role
            String roleId = condition.getProperty(ItscUserInfo.PROPERTY_USER_ROLEID);
            if (!StringUtils.isEmpty(roleId)) {
                detachedCriteria = detachedCriteria.add(Expression.eq(ItscUserInfo.PROPERTY_USER_ROLEID,
                        Integer.valueOf(roleId)));
            }
        }

        return userDao.findByCriteria(detachedCriteria);
    }

    public PageInfo findUsersByCondition(Properties condition, int startIndex, int pageSize) {
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(ItscUserInfo.class);

        if (condition != null && !condition.isEmpty()) {

            // user name
            String userName = condition.getProperty(ItscUserInfo.PROPERTY_USER_NAME);
            if (!StringUtils.isEmpty(userName)) {
                detachedCriteria = detachedCriteria.add(Expression.ilike(ItscUserInfo.PROPERTY_USER_NAME,
                        userName, MatchMode.ANYWHERE));
            }

            // user chinese name
            String userChName = condition.getProperty(ItscUserInfo.PROPERTY_USER_CHINESE_NAME);
            if (!StringUtils.isEmpty(userChName)) {
                detachedCriteria = detachedCriteria.add(Expression.ilike(ItscUserInfo.PROPERTY_USER_CHINESE_NAME,
                        userChName, MatchMode.ANYWHERE));


                // role
                String roleId = condition.getProperty(ItscUserInfo.PROPERTY_USER_ROLEID);
                if (!StringUtils.isEmpty(roleId)) {
                    detachedCriteria = detachedCriteria.add(Expression.eq(ItscUserInfo.PROPERTY_USER_ROLEID,
                            Integer.valueOf(roleId)));
                }
            }       
        }
        return userDao.findPageByCriteria(detachedCriteria, startIndex, pageSize);
    }

    public List<ItscUserInfo> findUsersByRoleId(Integer roleId) {
        return findUsersByRoleId(roleId);
    }

    public PageInfo findUsersByPage(int pageSize, int startIndex) {
        return userDao.FindAllByPage(pageSize, startIndex);
    }

    public void addUser(ItscUserInfo userInfo) throws UserAlreadyExistException {

        // 用户是否已存在
        ItscUserInfo user = userDao.findUserByName(userInfo.getUserName());
        if (user != null) {
            throw new UserAlreadyExistException();
        }
        userDao.save(userInfo);
    }

    public void updateUser(ItscUserInfo userInfo) throws UserNotExistException, UserAlreadyExistException {
        // could not change a name which already exists
        ItscUserInfo user = userDao.findUserByName(userInfo.getUserName());
        if (!user.equals(userInfo)) {
            throw new UserAlreadyExistException();
        }
        try {
            userDao.merge(userInfo);
        } catch (DataAccessException dae) {
            // tranlate the exception for the user has already been removed
            user = userDao.findById(userInfo.getUserId());
            if (user == null) {
                throw new UserNotExistException();
            }
            // throw the exception for other conditions
            throw dae;
        }
    }

    public void removeUser(Integer userId) throws UserNotExistException {
        // delete it
        try {
            userDao.removeById(userId);
        } catch (DataAccessException dae) {
            // role does not exist
            ItscUserInfo roleInfo = userDao.findById(userId);
            if (roleInfo == null) {
                throw new UserNotExistException();
            }
            // throw it when other conditions
            throw dae;
        }
    }

    public void lockUser(Integer userId) throws UserNotExistException {
        ItscUserInfo user = userDao.findById(userId);
        user.setLocked(true);
        userDao.update(user);
        // need to clear the session
        return;
    }

    public void unlockUser(Integer userId) throws UserNotExistException {
        ItscUserInfo user = userDao.findById(userId);
        user.setLocked(false);
        userDao.update(user);
        return;
    }

    public List<ItscUserInfo> findAllUsers() {
        return userDao.FindAll();
    }
}
